package com.project.aspect;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Field;

@Component
@Aspect//申明该类为切面类
public class SpringAspect {
    //会话工厂
    private static SqlSessionFactory factory;

    static {
        try {
            Reader r = Resources.getResourceAsReader("mybatis.cfg.xml");
            factory = new SqlSessionFactoryBuilder().build(r);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Around("execution(* com.project.Serivce..*.*(..))")
    public Object around(ProceedingJoinPoint point) throws Exception {
        //获取目标对象
        Object targetObj = point.getTarget();
        //打开会话
        SqlSession session = factory.openSession();
        //得到所有属性的数组
        Field[] fieldArray = targetObj.getClass().getDeclaredFields();
        for (Field f : fieldArray) {
            if (f.getType().isInterface()) {//如果属性的模板是一个接口
                f.setAccessible(true);
                //获取mapper对象
                Object mapper = session.getMapper(f.getType());
                //将mapper赋给该属性
                f.set(targetObj, mapper);
            }
        }
        try {
            //执行目标对象的目标方法
            Object returnObj = point.proceed();
            session.commit();
            return returnObj;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            session.rollback();
        } finally {
            session.close();
        }

        return null;
    }
}
